package com.health.medicine.service.impl;


import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.health.api.client.UserClient;
import com.health.api.model.hospital.GetHospitalInfoRequest;
import com.health.api.model.hospital.HospitalVO;
import com.health.common.auth.service.TokenService;
import com.health.common.common.ErrorCode;
import com.health.common.exception.BusinessException;
import com.health.common.model.user.LoginUser;
import com.health.common.service.util.SDKUtils;
import com.health.medicine.mapper.MedicineInfoMapper;
import com.health.medicine.model.dto.medicine.AddDrugInfoRequest;
import com.health.medicine.model.dto.medicine.PageQueryDrugInfoRequest;
import com.health.medicine.model.entity.Manufacturer;
import com.health.medicine.model.entity.MedicineInfo;
import com.health.medicine.model.entity.TransportRecords;
import com.health.medicine.model.enums.MedicineTypeEnums;
import com.health.medicine.service.ManufacturerService;
import com.health.medicine.service.MedicineInfoService;
import com.health.medicine.service.TransportrecordsService;
import jakarta.annotation.Resource;
import org.fisco.bcos.sdk.v3.codec.ContractCodecException;
import org.fisco.bcos.sdk.v3.transaction.model.exception.TransactionBaseException;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import static com.health.common.constant.ContractConstants.ADD_DRUG_INFO;

/**
* @author zhexueqi
* @description 针对表【medicine_info】的数据库操作Service实现
* @createDate 2024-08-29 15:46:44
*/
@Service
public class MedicineInfoServiceImpl extends ServiceImpl<MedicineInfoMapper, MedicineInfo>
    implements MedicineInfoService {

    @Resource
    private SDKUtils sdkUtils;

    @Value("${system.contract.contractName}")
    private String CONTRACT_NAME;
    @Value("${system.contract.address}")
    private String CONTRACT_ADDRESS;

    @Resource
    private MedicineInfoMapper medicineInfoMapper;

    @Resource
    private ManufacturerService manufacturerService;

    @Resource
    private TransportrecordsService transportrecordsService;

    @Resource
    private UserClient userClient;

    @Resource
    private TokenService tokenService;

    @Override
    public long produce(AddDrugInfoRequest addDrugInfoRequest) throws TransactionBaseException, ContractCodecException {
        if (addDrugInfoRequest == null){
            return 0L;
        }
        //获取到当前登录用户的账号
        LoginUser loginUser = tokenService.getLoginUser();
        String userAccount = loginUser.getUserAccount();
        Manufacturer manufacturer = manufacturerService.getOne(new QueryWrapper<Manufacturer>().eq("account", userAccount));

        MedicineInfo medicineInfo = new MedicineInfo();
        BeanUtil.copyProperties(addDrugInfoRequest,medicineInfo);

        //设置生产商id
        medicineInfo.setManufacturerId(manufacturer.getId());
        MedicineTypeEnums medicineTypeByCode = MedicineTypeEnums.getMedicineTypeByCode(addDrugInfoRequest.getDrugType());
//        medicineInfo.setDrugType(medicineTypeByCode);
        int traceId = medicineInfoMapper.insert(medicineInfo);
        if (traceId <= 0){
            throw new BusinessException(ErrorCode.SQL_ERROR,"保存药品信息失败");
        }

        //通过收货地地址获取到医院信息
        GetHospitalInfoRequest getHospitalInfoRequest = new GetHospitalInfoRequest();
        getHospitalInfoRequest.setHospitalAddress(addDrugInfoRequest.getReceiverAddress());
        HospitalVO hospitalInfo = userClient.getHospitalInfo(getHospitalInfoRequest);

        //保存运输记录
        TransportRecords transportRecords = new TransportRecords();
        transportRecords.setTraceId(Long.valueOf(medicineInfo.getId()));
        transportRecords.setDestination(hospitalInfo.getCoord());
        transportRecords.setTransportUnitId(addDrugInfoRequest.getTransporterId());
        transportRecords.setTransportQuantity(addDrugInfoRequest.getTransportQuantity());
        assert medicineTypeByCode != null;
        transportRecords.setTransportType("药品");

        boolean save = transportrecordsService.save(transportRecords);
        if (!save){
            throw new BusinessException(ErrorCode.SQL_ERROR,"保存运输记录失败");
        }

        List<Object> funcParams = new ArrayList<>();
        funcParams.add(traceId);
        funcParams.add(addDrugInfoRequest.getDrugName());
        funcParams.add(addDrugInfoRequest.getProductionDate().toString());
        funcParams.add(addDrugInfoRequest.getExpirationDate().toString());
        funcParams.add(addDrugInfoRequest.getReceiverAddress());

        //调用合约方法上链
        sdkUtils.sendTransaction(CONTRACT_NAME, CONTRACT_ADDRESS, ADD_DRUG_INFO, funcParams, addDrugInfoRequest.getPrivateKey());

        return traceId;
    }

    @Override
    public Page<MedicineInfo> pageDrugInfo(PageQueryDrugInfoRequest pageQueryDrugInfoRequest) {
        if (pageQueryDrugInfoRequest == null){
            return new Page<>();
        }
        if (pageQueryDrugInfoRequest.getCurrent() <= 0 || pageQueryDrugInfoRequest.getPageSize() <= 0){
            throw new BusinessException(ErrorCode.PARAMS_NULL,"分页参数不正确");
        }
        QueryWrapper<MedicineInfo> queryWrapper = getMedicineInfoQueryWrapper(pageQueryDrugInfoRequest);

        queryWrapper.orderByDesc("id");
        Page<MedicineInfo> page = new Page<>(pageQueryDrugInfoRequest.getCurrent(), pageQueryDrugInfoRequest.getPageSize());
        return medicineInfoMapper.selectPage(page,queryWrapper);
    }

    @Override
    public Manufacturer getManufacturerByCode(String medicineCode) {
        if (medicineCode == null || medicineCode.isBlank()){
            return null;
        }
        //先查到药物信息
        MedicineInfo medicineInfo = this.getById(medicineCode);
        if (medicineInfo == null){
            return null;
        }
        //再查到生产商信息
        Long manufacturerId = medicineInfo.getManufacturerId();
        if (manufacturerId == null){
            return null;
        }
        return manufacturerService.getById(manufacturerId);
    }

    @Override
    public MedicineInfo getDrugInfoByCode(String medicineCode) {
        if (medicineCode == null || medicineCode.isBlank()){
            return null;
        }
        return this.getById(medicineCode);
    }

    private @NotNull QueryWrapper<MedicineInfo> getMedicineInfoQueryWrapper(PageQueryDrugInfoRequest pageQueryDrugInfoRequest) {
        QueryWrapper<MedicineInfo> queryWrapper = new QueryWrapper<>();

        if (!pageQueryDrugInfoRequest.getDrugName().isBlank()){
            queryWrapper.like("drug_name", pageQueryDrugInfoRequest.getDrugName());
        }
        if (!pageQueryDrugInfoRequest.getDrugType().isBlank()){
            queryWrapper.like("drug_type", pageQueryDrugInfoRequest.getDrugType());
        }
        if (!pageQueryDrugInfoRequest.getDrugForm().isBlank()){
            queryWrapper.like("drug_form", pageQueryDrugInfoRequest.getDrugForm());
        }
        if (!pageQueryDrugInfoRequest.getDrugSpec().isBlank()){
            queryWrapper.like("drug_spec", pageQueryDrugInfoRequest.getDrugSpec());
        }
        if (!pageQueryDrugInfoRequest.getDrugUnit().isBlank()){
            queryWrapper.like("drug_unit", pageQueryDrugInfoRequest.getDrugUnit());
        }

        return queryWrapper;
    }
}




